-- 
-- We include instructions for customizing the empty product.
--

-- Set the module name to the product's main module
module HplProducts.Empty where

-- Add imports for product-specific modules
import FeatureModel.Types
--import EmptyTypes

-- Add embedding constructors for product-specific transformations
data TransformationModel = UndefinedTransformation

-- Add equations for product-specific transformations
transform :: TransformationModel -> SPLModel -> InstanceModel -> InstanceModel
transform UndefinedTransformation _ _ = undefined

mkEmptyInstance :: FeatureConfiguration -> InstanceModel
mkEmptyInstance fc =
  InstanceModel {
       featureConfiguration = fc
       -- Add product-specific model parts
  }
  
-- The following code depends on the above declarations.

type ConfigurationKnowledge = [ConfigurationItem]

data ConfigurationItem =
     ConfigurationItem {
       expr :: FeatureExpression,
       transformations :: [TransformationModel]
     }


build :: FeatureModel                 -- ^ SPL feature model    
      -> FeatureConfiguration         -- ^ selection of features, which characterizes t
      -> ConfigurationKnowledge       -- ^ relationships between features and transformations
      -> SPLModel                     -- ^ SPL assets
      -> InstanceModel             -- ^ resulting instance of the build process
build fm fc ck spl = stepRefinement ts spl emptyInstance       
 where 
  emptyInstance = mkEmptyInstance fc
  ts = tasks ck fc      
        
tasks :: ConfigurationKnowledge -> FeatureConfiguration -> [TransformationModel]
tasks ck fc = concat [transformations c | c <- ck, eval fc (expr c)]
stepRefinement :: [TransformationModel] -> SPLModel -> InstanceModel -> InstanceModel
stepRefinement [] splModel instanceModel = instanceModel
stepRefinement (t:ts) splModel instanceModel
 = stepRefinement ts splModel (transform t splModel instanceModel)

